﻿using System;
using System.Runtime.CompilerServices;
using Negocio.Seguridad;
using Negocio.Osd.OsdBase;
using Negocio.Generico;

namespace Negocio.Osd 
{
    public class osdSeguridad
    {
        #region Singleton

        private static osdSeguridad instance = null;

        private osdSeguridad() 
        {
            //Constructor vacio
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public static osdSeguridad GetInstance() 
        {
            if (instance == null) 
            {
                instance = new osdSeguridad();
            }
            return instance;
        }

        #endregion

        #region Metodos publicos

        /// <summary>
        /// Funcion que valida el DNI con la base de datos de usuarios
        /// </summary>
        /// <param name="DNI">DNI codificado</param>
        /// <returns>Valor booleano que determina su existencia</returns>
        public bool CompruebaDni(string DNI) 
        {
            bool isValid = false;
            string cad = Base64_Encode(DNI);
            try 
            {
                using (SeguridadClient servicio = new SeguridadClient()) 
                {
                    if (servicio.CompruebaDni(cad)) 
                    {
                        isValid = true;
                    }
                }
                return isValid;       
            }catch(Exception ex)
            {
                throw new OsdException(ex);
            }
        }

        /// <summary>
        /// Funcion que valida el DNI con la base de datos de usuarios
        /// </summary>
        /// <param name="DNI">DNI codificado</param>
        /// <returns>Valor booleano que determina su existencia</returns>
        public bool Login(string Nick, string userHash)
        {
            bool isValid = false;

            string userHashFormat = md5(userHash);
            try
            {
                using (SeguridadClient servicio = new SeguridadClient())
                {
                    if (servicio.Login(Nick, userHashFormat))
                    {
                        isValid = true;
                    }
                }
                return isValid;
            }
            catch (Exception ex)
            {
                throw new OsdException(ex);
            }
        }

        /// <summary>
        /// Comprueba si hay un nick ya dentro de la base de datos
        /// </summary>
        /// <param name="nick">Cadena con el nick que se va a validar</param>
        /// <returns></returns>
        public bool CompruebaNick(string nick) 
        {
            bool isValid = false;
            try
            {
                using (SeguridadClient servicio = new SeguridadClient())
                {
                    if (servicio.CompruebaNick(nick))
                    {
                        isValid = true;
                    }
                }
                return isValid;
            }
            catch (Exception ex) 
            {
                throw new OsdException(ex);
            }
        }

        #endregion

        #region Metodos privados

        /// <summary>
        /// Funcion que codifica una cadena de texto en base64
        /// </summary>
        /// <param name="str">Cadena a sin codificar</param>
        /// <returns>Cadena codificada</returns>
        private static string Base64_Encode(string str)
        {
            byte[] encbuff = System.Text.Encoding.UTF8.GetBytes(str);
            return Convert.ToBase64String(encbuff);
        }


        public static string md5(string Value)
        {
            System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] data = System.Text.Encoding.ASCII.GetBytes(Value);
            data = x.ComputeHash(data);
            string ret = "";
            for (int i = 0; i < data.Length; i++)
                ret += data[i].ToString("x2").ToLower();
            return ret;
        }

        #endregion
    }
}